fix(daemon): drop prior session when agent is renamed (MUL-5736) - #5909
Open
kakiuwang-ui wants to merge 1 commit into
Open
fix(daemon): drop prior session when agent is renamed (MUL-5736)#5909kakiuwang-ui wants to merge 1 commit into
kakiuwang-ui wants to merge 1 commit into
Conversation
…tity contamination (MUL-5736) When an agent is renamed (e.g. "Reviewer" → "Backend Builder"), the workdir from its last run still holds a CLAUDE.md whose ## Agent Identity section names the old role. Resuming that session means the conversation history has already established the old identity, causing the agent to misidentify itself and refuse tasks — the behaviour reported in MUL-5736. Fix: before overwriting CLAUDE.md with the new identity, read the name already recorded in the managed marker block. If it differs from the current agent name, drop PriorSessionID and start a fresh conversation. The check runs after gateCodexResumeToRolloutPresence while the old file is still on disk. The drop does not set PriorSessionResumeUnavailable because a rename is intentional: the user changed the agent's identity on purpose, so a fresh session is expected behaviour rather than an unexpected loss to surface. ReadPriorAgentName is added to execenv so the parsing logic is testable in isolation; gateResumeToSameAgentName wraps the daemon-level gate.
|
@kakiuwang-ui is attempting to deploy a commit to the IndexLabs Team on Vercel. A member of the Team first needs to authorize it. |
kakiuwang-ui
added a commit
to kakiuwang-ui/multica
that referenced
this pull request
Aug 3, 2026
…multica-ai#5760) Reduced to the ACP-sniffer half per maintainer guidance on multica-ai#5785: the poisoned-session classification (classifyPoisonedError branches), the session-exclusion queries, and the daemon carry-forward are all dropped — multica-ai#6083 (taskfailure.UnresumableHistory) and migration 234 (retired_session_id) now own that layer on main. The agent-rename gate (MUL-5736) is tracked separately in multica-ai#5909. What remains is the non-redundant fix nothing on main replaces: the ACP adapter was swallowing the provider error and reporting stopReason=end_turn, so a kimi 400 landed as status=completed with empty output. Everything in multica-ai#6083 keys off Result.Error; if the adapter never surfaces the error there, none of it can see the failure. - acpErrorHeaderRe / acpErrorDetailRe / acpTerminalErrorRe now recognise kimi's emoji-less `provider.api_error: NNN` lines; terminal only for 400/401/403 (429/408 are adapter-retried and must stay completed). - messageLocked forwards the status prefix via providerApiErrorStatusRe so the surfaced Result.Error carries `provider.api_error: 400`, which taskfailure.UnresumableHistory on main then classifies. - isPoisonedHistory() detects the 400 + "must not be empty" fingerprint across kimi's two-line stderr format and sets Result.ResumeRejected in both the hermes and kimi backends — the positive backend signal the daemon reads alongside the string-based path. Tests: ACP sniffer recognition (400/5xx/429), isPoisonedHistory two-line detection, messageLocked status forwarding, and hermes/kimi backend ResumeRejected (set on resume, not on a fresh run).
kakiuwang-ui
added a commit
to kakiuwang-ui/multica
that referenced
this pull request
Aug 3, 2026
…multica-ai#5760) Reduced to the ACP-sniffer half per maintainer guidance on multica-ai#5785: the poisoned-session classification (classifyPoisonedError branches), the session-exclusion queries, and the daemon carry-forward are all dropped — multica-ai#6083 (taskfailure.UnresumableHistory) and migration 234 (retired_session_id) now own that layer on main. The agent-rename gate (MUL-5736) is tracked separately in multica-ai#5909. What remains is the non-redundant fix nothing on main replaces: the ACP adapter was swallowing the provider error and reporting stopReason=end_turn, so a kimi 400 landed as status=completed with empty output. Everything in multica-ai#6083 keys off Result.Error; if the adapter never surfaces the error there, none of it can see the failure. - acpErrorHeaderRe / acpErrorDetailRe / acpTerminalErrorRe now recognise kimi's emoji-less `provider.api_error: NNN` lines; terminal only for 400/401/403 (429/408 are adapter-retried and must stay completed). - messageLocked forwards the status prefix via providerApiErrorStatusRe so the surfaced Result.Error carries `provider.api_error: 400`, which taskfailure.UnresumableHistory on main then classifies. - isPoisonedHistory() detects the 400 + "must not be empty" fingerprint across kimi's two-line stderr format and sets Result.ResumeRejected in both the hermes and kimi backends — the positive backend signal the daemon reads alongside the string-based path. Tests: ACP sniffer recognition (400/5xx/429), isPoisonedHistory two-line detection, messageLocked status forwarding, and hermes/kimi backend ResumeRejected (set on resume, not on a fresh run).
kakiuwang-ui
added a commit
to kakiuwang-ui/multica
that referenced
this pull request
Aug 9, 2026
…multica-ai#5760) Reduced to the ACP-sniffer half per maintainer guidance on multica-ai#5785: the poisoned-session classification (classifyPoisonedError branches), the session-exclusion queries, and the daemon carry-forward are all dropped — (retired_session_id) now own that layer on main. The agent-rename gate (MUL-5736) is tracked separately in multica-ai#5909. What remains is the non-redundant fix nothing on main replaces: the ACP adapter was swallowing the provider error and reporting stopReason=end_turn, so a kimi 400 landed as status=completed with empty output. Everything in none of it can see the failure. - acpErrorHeaderRe / acpErrorDetailRe / acpTerminalErrorRe now recognise kimi's emoji-less `provider.api_error: NNN` lines; terminal only for 400/401/403 (429/408 are adapter-retried and must stay completed). - messageLocked forwards the status prefix via providerApiErrorStatusRe so the surfaced Result.Error carries `provider.api_error: 400`, which taskfailure.UnresumableHistory on main then classifies. - isPoisonedHistory() detects the 400 + "must not be empty" fingerprint across kimi's two-line stderr format and sets Result.ResumeRejected in both the hermes and kimi backends — the positive backend signal the daemon reads alongside the string-based path. Tests: ACP sniffer recognition (400/5xx/429), isPoisonedHistory two-line detection, messageLocked status forwarding, and hermes/kimi backend ResumeRejected (set on resume, not on a fresh run).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
## Agent Identitysection records the old name. Resuming that session causes the conversation history to assert the old identity; even thoughInjectRuntimeConfigoverwrites the file with the new name, the resumed turns have already established the wrong role — which is why Backend Builder called itself "Reviewer" and refused tasks in MUL-5736.gateResumeToSameAgentNamereads the name from the existing managed marker block. A mismatch dropsPriorSessionIDand clearsPriorSessionResumed, so the run starts fresh with the correct identity.ReadPriorAgentNameis added toexecenvso the parse logic is independently testable.PriorSessionResumeUnavailable— an agent rename is intentional, so a fresh session is the expected outcome, not a loss to disclose.Test plan
TestReadPriorAgentName— verifies correct extraction of the agent name from the managed block for all edge cases (name with/without ID suffix, missing file, no marker block, no identity section, unknown provider).TestGateResumeToSameAgentName— verifies the gate drops the session on name change, keeps it on match, and is a no-op when there is no prior session, no current agent name, or no config file../server/internal/daemon/...suite passes.